package Rete;

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.logging.*;
import java.util.regex.*;

public class Utils {
    public static String trovaGateway()
    {
        String ipGateway = null;
        String _255 = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
      String exIP = "(?:" + _255 + "\\.){3}" + _255;
      Pattern pat = Pattern.compile("^\\s*(?:0\\.0\\.0\\.0\\s*){1,2}("+exIP+").*");
      Process proc;
      try {
         proc = Runtime.getRuntime().exec("netstat -rn");
         InputStream inputstream = proc.getInputStream();
         InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
         BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
         String line;
         while ((line = bufferedreader.readLine()) != null) {
            Matcher m = pat.matcher(line);
            if(m.matches()){
               ipGateway = m.group(1);
               System.out.println("Gateway: "+ipGateway);

            }
         }
      } catch (IOException ex) {
         Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
      }
      return ipGateway;
    }
    public static HashMap<String,String> trovaInterfacce()
    {
        HashMap<String,String> reti = new HashMap<String,String>();
		try {
			for (
			    final Enumeration< NetworkInterface > interfaces =
			        NetworkInterface.getNetworkInterfaces( );
			    interfaces.hasMoreElements( );
			)
			{
			    final NetworkInterface cur = interfaces.nextElement( );

			    if ( cur.isLoopback( ) )
			    {
			        continue;
			    }

			 //   System.out.println( "interface " + cur.getName( ) );

			    for ( final InterfaceAddress addr : cur.getInterfaceAddresses( ) )
			    {
			        final InetAddress inet_addr = addr.getAddress( );

			        if ( !( inet_addr instanceof Inet4Address ) )
			        {
			            continue;
			        }

	//		        System.out.println("  address: " + inet_addr.getHostAddress( ) +"/" + addr.getNetworkPrefixLength( ) );
	//		        System.out.println("  broadcast address: " +addr.getBroadcast( ).getHostAddress( ));
			       // reti.put(cur.getName( ), inet_addr.getHostAddress( ));
			        reti.put(cur.getDisplayName(), inet_addr.getHostAddress( ));
			    }
			}
		}
                catch (SocketException e) {}
		System.out.println("------------------------------------------------");
		Iterator<String> nomeReti = reti.keySet().iterator();
		for (int i=0;i<reti.size();i++)
		{
			String nome = nomeReti.next();
			System.out.println(nome);
			System.out.println(reti.get(nome));
		}
                return reti;
    }
    public static String trovaProprioIP()
    {
        String proprioIP = null;
        String ipGateway = trovaGateway();
        HashMap<String,String> interfacceDiRete = trovaInterfacce();
        Iterator<String> nomeReti = interfacceDiRete.keySet().iterator();

        StringTokenizer t = new StringTokenizer(ipGateway);
        String ipRete = t.nextToken(".")+"."+t.nextToken(".")+"."+t.nextToken(".");
	for (int i=0;i<interfacceDiRete.size();i++)
        {
            String nome = nomeReti.next();
            t = new StringTokenizer(interfacceDiRete.get(nome));
            String ipInterfaccia = t.nextToken(".")+"."+t.nextToken(".")+"."+t.nextToken(".");
            if (ipInterfaccia.equals(ipRete))
            {
                proprioIP = interfacceDiRete.get(nome);
                System.out.println("IP giocatore: "+ proprioIP);
            }

       //     System.out.println(nome);
       //     System.out.println(interfacceDiRete.get(nome));
        }
        return proprioIP;
    }

    public static void inviaStringaSuSocket(String messaggio, DatagramSocket socket, String ipDestinatario, int portaDestinatario)
    {
        System.out.println(messaggio);
        byte[] buf = new byte[256];
        InetAddress addr = null;
        try {
            addr = InetAddress.getByName(ipDestinatario);
        } catch (UnknownHostException ex) {
            System.out.println("problemi con l'ip del destinatario");
            Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
        }
        DatagramPacket packet = new DatagramPacket(buf, buf.length, addr, portaDestinatario);
        ByteArrayOutputStream boStream = new ByteArrayOutputStream();
        DataOutputStream doStream = new DataOutputStream(boStream);
        try
        {
            doStream.writeUTF(messaggio);
            byte[] data = boStream.toByteArray();
            packet.setData(data); // IMPOSTO IL CONTENUTO DEL PACCHETTO
            socket.send(packet);
        }
        catch (IOException ex) {Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);}
    }

    public static String riceviStringaDaSocket(DatagramSocket socket)
    {
        return riceviStringaDaSocket(socket,0);
    }
    public static String riceviStringaDaSocket(DatagramSocket socket, int timeout)
    {
        String messaggio = null;
        byte[] buf = new byte[256];
        DatagramPacket packet  = new DatagramPacket(buf, buf.length);
        try {
            socket.setSoTimeout(timeout);
        } catch (SocketException ex) {
            Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
        }
        packet.setData(buf);
        try
        {
            socket.receive(packet);
            ByteArrayInputStream biStream = new ByteArrayInputStream(packet.getData(), 0, packet.getLength());
            DataInputStream diStream = new DataInputStream(biStream);
            messaggio = diStream.readUTF();
        } catch (IOException ex) {
            Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
        }
        return messaggio;
    }

    //restituisco array con [0]=messaggio [1]=ipMittente [2]=portaMittente
    public static String[] riceviStringaConInfoDaSocket(DatagramSocket socket)
    {
        return riceviStringaConInfoDaSocket(socket,0);
    }
    public static String[] riceviStringaConInfoDaSocket(DatagramSocket socket, int timeout)
    {
        String messaggio = null;
        byte[] buf = new byte[256];
        DatagramPacket packet  = new DatagramPacket(buf, buf.length);
        try {
            socket.setSoTimeout(timeout);
        } catch (SocketException ex) {
            Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
        }
        packet.setData(buf);
        try
        {
            socket.receive(packet);
            ByteArrayInputStream biStream = new ByteArrayInputStream(packet.getData(), 0, packet.getLength());
            DataInputStream diStream = new DataInputStream(biStream);
            messaggio = diStream.readUTF();
        } catch (IOException ex) {
            Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
        }
        String[] info = new String[3];
        info[0] = messaggio;
        info[1] = packet.getAddress().getHostAddress();
        info[2] = packet.getPort()+"";
        return info;
    }

    public static void dormi(int millisecondi)
    {
        try {
            Thread.sleep(millisecondi);
        } catch (InterruptedException ex) {
            Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
